#include "UserManager.h"

//确保用户计数器文件存在且里面有正确的值

//全局变量
UserManager user_manager;

UserManager::UserManager() {
    // 读取用户计数器

    ifstream counter_file(COUNTER_FILE);
    if(counter_file.is_open()){
        counter_file >> user_count;
        counter_file.close();
    }
    else{
        user_count = 0;
    }
}
UserManager::~UserManager() {
    save_counter_file();
}
void UserManager::save_counter_file() {
    // 保存用户计数器
    ofstream counter_file;
    counter_file.open(COUNTER_FILE,ios::out|ios::trunc);
    counter_file << user_count;
    counter_file.close();
}

string UserManager::get_user_pwd_dir(const int&id)const {
    return USER_FILE_DIR+to_string(id/USERS_PER_FILE)+"_ID/";
}

string UserManager::get_user_file_path(const int&id)const{
    return get_user_pwd_dir(id)+to_string(id)+".json";
}

string UserManager::get_user_chat_list_dir(const int&id)const{
    return USER_FILE_DIR+to_string(id/(USERS_PER_FILE))+"chat_list/";
}

string UserManager::get_user_chat_list_path(const int&id)const{
    return get_user_chat_list_dir(id)+to_string(id)+".json";
}

int UserManager::open_file(const string& file_path, ifstream& ifs) const{
    ifs.open(file_path,ios::in);
    if(!ifs.is_open()){
        PRINT_ERRNO_AND_STRERROR(LOG_INFO,"Failed to open file %s,try",file_path.c_str());
        return UserErr::file_err; //表示文件错误
    }
    return UserErr::success;
}

int UserManager::open_file(const string& file_path, ofstream& ofs) const{
    ofs.open(file_path,ios::out);
    if(!ofs.is_open()){
        PRINT_ERRNO_AND_STRERROR(LOG_INFO,"Failed to open file %s,try",file_path.c_str());
        return UserErr::file_err; //表示文件错误
    }
    return UserErr::success;
}


int UserManager::load_user_info(const int&id,json&user_info) {
    ifstream is;    
    fs::path user_file_path(get_user_file_path(id));
    if(!fs::exists(user_file_path)){
        user_info = {};
        return UserErr::non_exist; //文件不存在，返回空json
    }
    is.open(user_file_path,ios::in);
    //避免空文件json解析失败
    if (is.peek() == ifstream::traits_type::eof()) {
        user_info = {}; 
        is.close();
        return UserErr::success;
    }

    is >> user_info;
    is.close();
    return UserErr::success;
}


int UserManager::load_user_info(const int&id)  {
    int result=0;
    json user_info;
    if(load_user_info(id,user_info)!=UserErr::success){
        return UserErr::non_exist; //表示文件错误
    }
    this->user_info[id]=User(user_info);
    return UserErr::success;
}

int UserManager::quick_load_user_info(const int& id,User&user){
    if(this->user_info.find(id)==this->user_info.end()){
        if(load_user_info(id)!=UserErr::success){
            return UserErr::non_exist; //表示文件错误
        }
    }
    user=this->user_info[id];
    return UserErr::success;
}

int UserManager::quick_load_user_info(const int& id){
    if(this->user_info.find(id)==this->user_info.end()){
        if(load_user_info(id)!=UserErr::success){
            return UserErr::non_exist; //表示文件错误
        }
    }
    return UserErr::success;
}

int UserManager::save_user_info(const int&id,const json&user_info){
    fs::path user_pwd_dir(get_user_pwd_dir(id));

    ofstream os;
    //创建用户密码目录
    if(!fs::exists(user_pwd_dir)){
        fs::create_directories(user_pwd_dir);
    }

    if(open_file(get_user_file_path(id),os)!=UserErr::success){
        return UserErr::file_err; //表示文件错误
    }
    os << user_info.dump(4);
    os.close();
    return UserErr::success;
}

int UserManager::load_user_chat_list(const int&id,json&chat_list){
    ifstream chat_list_file;
    fs::path user_chat_list_path(get_user_chat_list_path(id));
    
    if(!fs::exists(user_chat_list_path))  {   
        chat_list = {};
        return UserErr::non_exist;
    };

    chat_list_file.open(user_chat_list_path,ios::in);


    if(chat_list_file.peek() == ifstream::traits_type::eof()){
        chat_list = {};
        chat_list_file.close();
        return UserErr::success;
    }

    chat_list_file >> chat_list;
    chat_list_file.close();
    return UserErr::success;
}

int UserManager::load_user_chat_list(const int&id){
    json chat_list_json;
    if(load_user_chat_list(id,chat_list_json)!=UserErr::success){
        return UserErr::file_err; //表示文件错误
    }
    this->user_chat_list_info[id]=ChatList(chat_list_json);
    return UserErr::success;
}

int UserManager::quick_load_user_chat_list(const int& id,ChatList&chat_list){
    if(this->user_chat_list_info.find(id)==this->user_chat_list_info.end()){
        if(load_user_chat_list(id)!=UserErr::success){
            return UserErr::file_err; //表示文件错误
        }
    }
    chat_list=this->user_chat_list_info[id];
    return UserErr::success;
}

int UserManager::quick_load_user_chat_list(const int& id){
    if(this->user_chat_list_info.find(id)==this->user_chat_list_info.end()){
        if(load_user_chat_list(id)!=UserErr::success){
            return UserErr::file_err; //表示文件错误
        }
    }
    return UserErr::success;
}


int UserManager::save_user_chat_list(const int&id,const json&chat_list){
    json old_chat_list;
    fs::path user_chat_dir(get_user_chat_list_dir(id));
    //创建用户聊天列表目录
    if(!fs::exists(user_chat_dir)){
       fs::create_directories(user_chat_dir);
    }

    ofstream chat_list_file;
    if(open_file(get_user_chat_list_path(id),chat_list_file)!=UserErr::success){
        return UserErr::file_err; //表示文件错误
    }


    #ifdef DEBUG
    cout<<"save_user_chat_list:"<<chat_list.dump(4)<<endl;
    cout<<"path"<<get_user_chat_list_path(id)<<endl;
    #endif

    chat_list_file << chat_list.dump(4);
    chat_list_file.close();

    return UserErr::success;
}

int UserManager::createUser(const string&name,const string& password)noexcept{
    int new_id = ++user_count;
    User new_user(new_id,name,password);
    this->user_info[new_id]=new_user;
    save_user_info(new_id,new_user.serialize());
    json j;
    j["LIST"]={};
    save_user_chat_list(new_id,j);


    return UserErr::success;
}

int UserManager::add_chat_list(const int& user_id, const string& chat_id){
    if(quick_load_user_chat_list(user_id)!=UserErr::success){
        #ifdef DEBUG
        cout<<"quick_load_user_chat_list failed"<<endl;
        #endif

        return UserErr::file_err; //表示文件错误
    }
    this->user_chat_list_info[user_id].add_chat(chat_id,"yes");

    #ifdef DEBUG
    cout<<this->user_chat_list_info[user_id].serialize().dump(4)<<endl;
    save_user_chat_list(user_id,this->user_chat_list_info[user_id].serialize());
    #endif

    return UserErr::success;
}

int UserManager::get_chat_list(const int& user_id, json& chat_list_json){
    ChatList chat_list;
    if(quick_load_user_chat_list(user_id,chat_list)!=UserErr::success){
        chat_list_json = {};
        return UserErr::file_err; //表示文件错误
    }
    chat_list_json=chat_list.serialize();
}



int UserManager::login(const int& id, const string& password,socketfd sockfd)noexcept{

    User user;
    if(quick_load_user_info(id,user)==UserErr::non_exist){
        PRINTF_LOG_AND_DEBUG(LOG_INFO,"User %d does not exist",id);
        return UserErr::non_exist; //表示文件错误
    }

    if(user.get_pwd()!=password){
        PRINTF_LOG_AND_DEBUG(LOG_INFO,"Wrong password for user %d",id);
        return UserErr::wrong_pwd;
    }
    add_online_user(id,sockfd);
    return UserErr::success;
}




int UserManager::logout(const int& id) noexcept{
    //TODO: 实现用户下线

    //从缓存中移除用户信息
    user_info_pwd.erase(id);
    user_chat_list.erase(id);

    //从在线用户列表中移除用户
    remove_online_user(id);
    return UserErr::success;
}


bool UserManager::is_online(const int&id)const noexcept{
    return this->online_users.find(id)!=this->online_users.end();
}

int UserManager::add_online_user(const int&id,const socketfd &sockfd)noexcept{
    this->online_users[id]=sockfd;
        return UserErr::success;
}//将用户信息加入到online_users中

int UserManager::remove_online_user(const int&id)noexcept{
    this->online_users.erase(id);
    return UserErr::success;
}//将用户信息从online_users中移除 

int UserManager::get_sockfd(const int&id)const noexcept{
    if(this->online_users.find(id)!=this->online_users.end()){
        return this->online_users[id];
    }
    else{
        PRINTF_LOG_AND_DEBUG(LOG_INFO,"User %d is not online\n",id);
    }
    return -1;
}

int UserManager::get_user_count()const noexcept{
    return user_count;
}


string UserManager::get_user_name(const int&id)noexcept{
    if(quick_load_user_info(id)!=UserErr::success){
        return "";
    }
    return this->user_info[id].get_name();
}
// ==============================

